package cbfg.rvadapter.selection

import cbfg.rvadapter.RVAdapter

interface ISelectionDelegate<T : Any> {

    fun setup(adapter: RVAdapter<T>, mutableItems: MutableList<T>)

    fun getSelections(): Collection<T>

    /** 查询当前是否是可选状态 */
    val isSelectable: Boolean

    /** 查询 item 是否被选中 */
    fun isSelected(item: T): Boolean

    /**
     * 设置某数据类型 item 是否可选，这个类型要配置过可选信息才行。
     */
    fun enableSelectable(selectable: Boolean) {
        enableSelectable(selectable, RVAdapter.RV_FLAG_DEFAULT)
    }

    /**
     * 设置某数据类型 item 是否可选，这个类型要配置过可选信息才行。
     * @param flags 可以是以下组合：
     * [RV_FLAG_CLEAR_SELECTIONS] 清空该数据类型的选中项
     * [RV_FLAG_NOTIFY_CHANGED] 刷新
     */
    fun enableSelectable(selectable: Boolean, flags: Int)

    /**
     * 选中 item
     * 该类型允许选择才可以选中
     * 该类型单选的话会判断移除先前选中项
     */
    fun selectAt(index: Int)

    /**
     * 按范围选择
     */
    fun selectRange(fromIndex: Int, toIndex: Int)

    /**
     * 多项选择
     */
    fun selectAll(list: Collection<T>, range: IntRange?)

    /**
     * 选中指定类型 item 所有数据，类型是单选的话只能选中一项
     */
    fun selectAll(clazz: Class<*>)

    fun selectAll()

    fun deselectAt(index: Int, needNotify: Boolean)

    fun deselect(item: T, needNotify: Boolean)

    fun deselectAll() {
        deselectAll(null, null, true)
    }

    fun deselectAll(needNotify: Boolean) {
        deselectAll(null, null, needNotify)
    }

    /**
     * 取消选中指定的项列表
     * @param list 要取消选中的项列表
     * @param range 项列表的范围，用于刷新指定范围的 item 状态，如果不连续则不传
     * @param needNotify true：通知刷新
     */
    fun deselectAll(list: Collection<T>, range: IntRange?, needNotify: Boolean)

    /**
     * 取消选中指定类型 item 所有数据
     *  @param range 项列表的范围，用于刷新指定范围的 item 状态，如果不连续则不传
     * @param needNotify true：刷新
     */
    fun deselectAll(clazz: Class<*>?, range: IntRange?, needNotify: Boolean)

    /**
     * 更新选中项状态
     * 1、可选才处理选中事件
     * 2、单选情况：
     *  已经选中该项的话不用再处理
     *  没有选中该项的情况下，先移除前面选中的，再添加当前的到选中列表
     * 3、多选情况：
     * 如果已经选中则移除选中，否则选中
     */
    fun toggleSelect(item: T, index: Int)
}